# -*- coding: utf-8 -*-
# @Time        :2025/4/21 20:35
# @Author      :文刀水寿
# @File        : student.py
"""
 @Description :
"""
from fastapi import APIRouter, Request
from fastapi import HTTPException
from models import *
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel, field_validator
from typing import List, Union

student_api = APIRouter()
templates = Jinja2Templates(directory="templates")


@student_api.get("/")
async def student():
    # (1) 查询所有， all
    # students = await Student.all()  # <tortoise.queryset.QuerySet object
    # print("Student:", students)
    # for stu in students:
    #     print(stu.name, stu.sno)

    # (2) 过滤查询, filter
    # students = await Student.filter(name="rain")  # <tortoise.queryset.QuerySet object
    # print("Student:", students)
    # for stu in students:
    #     print(stu.name, stu.sno)

    # (3) 返回值只有一个时， 过滤查询,get 返回模型类型对象
    # students = await Student.get(name="rain")  # <tortoise.queryset.QuerySet object
    # print(students.name)

    # (4) 模糊查询
    # students = await Student.filter(sno__gt=2001) #大于  # <tortoise.queryset.QuerySet object
    # students = await Student.filter(sno__lt=2001) #小于  # <tortoise.queryset.QuerySet object
    # students = await Student.filter(sno__in=2001) #等于  # <tortoise.queryset.QuerySet object
    # students = await Student.filter(sno__range=[1, 10000]) #范围  # <tortoise.queryset.QuerySet object
    # print("Student:", students)
    # for stu in students:
    #     print(stu.name, stu.sno)

    # （5） values查询
    stu = await Student.all().values("name", "sno")  # <tortoise.queryset.QuerySet object
    print(stu)
    # [{'name': 'rain', 'sno': 2001}, {'name': 'eric', 'sno': 2002}, {'name': 'avlin', 'sno': 2003}]

    # (6) 一对多查询，  多对多查询
    avlin = await Student.get(name="avlin")
    print(avlin.name)  # avlin
    print(avlin.pwd)  # 345
    print(avlin.sno)  # 2003
    print(await avlin.clas.values("name"))  # {'name': '计算机科学与技术1班'}

    # return {
    #     "操作：": "查看所有学生"
    # }

    students = await Student.all().values("name", "clas__name")
    print(await avlin.course.all().values("name", "teacher_name_id"))

    students = await Student.all().values("name", "clas__name", "course__name")

    return students


@student_api.get("/index.html")
async def student(request: Request):
    templates = Jinja2Templates(directory="templates")
    students = await Student.all()

    return templates.TemplateResponse(
        "index.html", {
            "request": request,
            "students": students
        }
    )


class StudentIn(BaseModel):
    name: str
    pwd: str
    sno: int
    # 一对多的联系
    clas_id: int
    # 多对多的联系
    course: List[int] = None

    @field_validator("name")
    def name_must_alpha(cls, value):
        assert value.isalpha(), 'name must alpha'
        return value

    @field_validator("pwd")
    def pwd_must_alpha(cls, value):
        # 检查密码长度
        if len(value) < 6:
            raise ValueError("Password must be at least 6 characters long")

        # 检查是否包含大写字母
        if not any(char.isupper() for char in value):
            raise ValueError("Password must contain at least one uppercase letter")

        # 检查是否包含小写字母
        if not any(char.islower() for char in value):
            raise ValueError("Password must contain at least one lowercase letter")

        # 检查是否包含数字
        if not any(char.isdigit() for char in value):
            raise ValueError("Password must contain at least one digit")

        # 检查是否包含特殊字符
        special_characters = "!@#$%^&*()-_=+[]{}|;:,.<>?/~`"
        if not any(char in special_characters for char in value):
            raise ValueError("Password must contain at least one special character")

        return value

    @field_validator("sno")
    def sno_must_alpha(cls, value):
        assert value > 1000 and value < 10000, '学号在1000-10000范围内'
        return value


@student_api.post("/")
async def add_student(student_in: StudentIn):
    # 插入到数据库
    # 方式1
    # 创建 Student 实例
    # addstudent = await Student(
    #     name=student_in.name,
    #     pwd=student_in.pwd,
    #     sno=student_in.sno,
    #     clas_id=student_in.clas_id
    # )
    # await addstudent.save()

    # 方式2
    addstudent = await Student.create(
        name=student_in.name,
        pwd=student_in.pwd,
        sno=student_in.sno,
        clas_id=student_in.clas_id
    )

    # 多对多的关系绑定
    choose_course = await Course.filter(id__in=student_in.course)
    # 清空该学生的绑定
    await addstudent.course.clear()
    await addstudent.course.add(*choose_course)

    return {
        "操作成功": f"{student_in.sno}已经被添加！！！"
    }


@student_api.put("/{student_id}")
async def getStudent(student_id: int):
    student = await Student.get(id=student_id)
    return student


@student_api.put("/{student_id}")
async def updateStudent(student_id: int, student_in: StudentIn):
    data = student_in.dict()
    print("data:", data)

    courses = data.pop("course")

    await student.filter(id=student_id).update(**data)

    # 设置多对多选修课

    edit_stu = await Student.get(id=student_id)
    choose_course = await Course.filter(id__in=courses)
    await edit_stu.course.clear()
    await edit_stu.course.add(*choose_course)

    return student


@student_api.delete("/{student_id}")
async def delete_student(student_id: int):
    deleteCount = await Student.filter(id=student_id).delete()

    if not deleteCount:
        raise HTTPException(status_code=404, detail=f"{student_id}学生不存在")

    return {
        "操作": "删除成功！！！"
    }
